<?php

namespace mongrove;

/**
 *
 * The FloatField is a container for floating point values.
 *
 * @author Gido Hakvoort <gido@hakvoort.it>
 * @author Michiel Hakvoort <michiel@hakvoort.it>
 *
 */
class FloatField extends SimpleField {

    protected $minimum;
    protected $maximum;
    protected $maximumInclusive;

    /**
     *
     * Create a new FloatField with a default value.
     *
     * @param float $default The default value
     */
    public function __construct($default = null) {
        parent :: __construct();

        if($default !== null) {
            $this->setValue($default);
        }
    }

    /**
     * Set the minimum allowed value of this field. This minimum value is inclusive.
     *
     * @param float|int $minimum The minimum required value.
     *
     * @throws \Exception When the passed value is not numeric
     *
     * @return FloatField
     */
    public function setMinimum($minimum) {
        if(!is_numeric($minimum)) {
            throw new \Exception("Minimum should be a numeric value.");
        }

        $this->minimum = floatval($minimum);
        return $this;
    }

    /**
     *
     * Set the maximum value this field can hold. By default this
     * value is inclusive, but can be set to be exclusive.
     *
     * @param float|int $maximum The maximum allowed value.
     * @param boolean $maximumInclusive Set to true if the maximum allowed value is inclusive.
     *
     * @throws \Exception When the passed value is not numeric
     *
     * @return FloatField
     */
    public function setMaximum($maximum, $maximumInclusive = true) {
        if(!is_numeric($maximum)) {
            throw new \Exception("Maximum should be a numeric value.");
        }

        $this->maximum = floatval($maximum);
        $this->maximumInclusive = $maximumInclusive;

        return $this;
    }

    /**
     * (non-PHPdoc)
     * @see src/mongrove.SimpleField::setValueImpl()
     */
    protected function setValueImpl($value) {
        if($this->value === $value) {
            return false;
        }

        if(($newValue = filter_var($value, FILTER_VALIDATE_FLOAT, array('flags' => FILTER_FLAG_ALLOW_THOUSAND))) === false) {
            throw new \Exception("{$value} is not a valid value for this field.");
        }

        $value = $newValue;

        if($this->minimum !== null && $value < $this->minimum) {
            throw new \Exception("{$value} is too low, should be at least {$this->minimum}.");
        }

        if($this->maximum !== null && ($value > $this->maximum || ((!$this->maximumInclusive) && ($value === $this->maximum)))) {
            throw new \Exception("{$value} is too high, should be lower than {$this->maximum}.");
        }

        $this->value = $value;

        return true;
    }
}